<template>
  <div>
    <div class="map" id="coordinates" ref="basicMapbox" :style="{height:domHeight + 'px',width:'100%'}"></div>
    <el-popover
      class="popover-style"
      placement="right-start"
      width="360"
      trigger="click">
        <div class="popover-list">
          <h4 style="margin:0 0 10px 0;">选择底图</h4>
          <el-row :gutter="20">
            <el-col :span="8" v-for="(item,index) in style.list" :key="index" class="item">
              <div :class="index == style.current ? 'img active' : 'img'" @click="changeStyle(index)" >
                <img :src="item.src" width="100%" height="60px" />
              </div>
                <div class="align-center p-t-10">{{ item.label }}</div>
            </el-col>
          </el-row>
        </div>
      <div slot="reference" class="btn">
        <img :src="selStyle.src" width="80px" height="60px" />
        <el-tag type="primary" effect="dark" class="tag">底图</el-tag>
      </div>
    </el-popover>
  </div>
</template>
<script>
import * as turf from '@turf/turf';
import * as mapboxgl from 'mapbox-gl';
import { stylesV8 } from '@/assets/js/config';
import cityGeoJson from '@/assets/geojson/city';
import {city, cityMapCenter, geoserver} from '@/config/env';
export default {
  props:{
    domHeight:{
      type: Number,
    },
    isPronvince:{
      type: Boolean,
      default: true
    },
    isCity:{
      type: Boolean,
      default: false,
    },
    zoom: {
      type: Number,
      default: 6.4,
    }
  },
  data(){
    return {
      map: null,
      mapboxToken: 'pk.eyJ1Ijoic25zcXNzIiwiYSI6ImNrZ2oxbWtqMTAzNnAyeXFwMDAzdmp2YTAifQ.AuaHmI9j-_VbOYxUSJACQw',
      mapChange: null,
      mapCenter: cityMapCenter, //[113.206144, 22.972300]
      marker: null,
      // zoom: 6.4,
      selStyle: stylesV8[1],
      interVal: null,
      style:{
        current: 1,
        list:stylesV8,
      },

      interVal: null,
      _map: null,
      __mapResolvers: [],
    }
  },
  created(){
    this.initMap();
  },
  destroyed() {
    if (this.interVal) {
      clearInterval(this.interVal);
    }
    this.removeCurrentMap();
  },
  async mounted() {
    if (!mapboxgl.supported()) {
      this.$message.warning('您当前使用的浏览器不支持 Mapbox GL 地图');
    }
    const map = await this.createMap();
    this.setMap(map);
  },
  methods: {
    changeStyle(index){
      this.style.current = index;
      this.selStyle = this.style.list[index];
      const styles = this.selStyle.url.split('/');
      if (this.map.getLayer('basemap-style-layer')) {
        this.map.removeLayer('basemap-style-layer');
      }
      if (this.map.getSource('basemap-style-source')) {
        this.map.removeSource('basemap-style-source');
      }
      if (this.selStyle.id === 'gd-road-simple') {
        this.map.addSource('basemap-style-source', {
          type: 'raster',
          tiles: [
            'http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}&scale=1&style=7'
          ],
          tileSize: 256
        });
      } else {
        this.map.addSource('basemap-style-source', {
          type: 'raster',
          scheme: 'xyz',
          tiles: [
            `https://api.mapbox.com/styles/v1/snsqss/${styles[styles.length - 1]}/tiles/512/{z}/{x}/{y}?access_token=${this.mapboxToken}`
          ]
        });
      }
      this.map.addLayer({
        id: 'basemap-style-layer',
        type: 'raster',
        source: 'basemap-style-source',
      }, 'split-layer');
    },
    async initMap(callback) {
      // this.map = await this.createMap();
      const map = await this.getMap();
      this.map = map;
      this.interVal = setInterval(() => {
        map.resize();
      });
      this.addStyleRaster();
      this.addBorder();
      if(typeof(callback) == 'function'){
        callback();
      }
    },
    createMap(){
      this.selStyle = this.selStyle ? this.selStyle : this.style.list[this.style.current];
      return new Promise((resolve, reject) => {
        const map = new mapboxgl.Map({
          accessToken: this.mapboxToken,
          container: this.$refs.basicMapbox,
          style: {
            version: 8,
            name: 'BlankMap',
            glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
            sources: {},
            layers: [
              {
                id: 'background',
                type: 'background',
                paint: {
                  'background-color': '#f0f2f5'
                }
              },
              {
                id: 'split-layer',
                type: 'background',
                paint: {
                  'background-color': 'rgba(0,0,0,0)'
                }
              },
            ]
          },
          // style: this.selStyle ? this.selStyle.url : stylesV8[0].url,
          center: this.mapCenter,
          zoom: this.zoom,
          attributionControl: false,
          logoPosition: 'bottom-right',
          bearing: 0,
          preserveDrawingBuffer: true,
        });
        map.addControl(new mapboxgl.NavigationControl({
          showZoom: false,
          showCompass: false,
          visualizePitch: false
        }), 'bottom-left');
        map.on('load', () => {
          resolve(map);
          this.map = map;
          this.fitBounds();
          // this.mapChange.emit(map);
        });
      });
    },
    getMap(){
    return new Promise((resolve, reject) => {
      if (!!this._map) {
        resolve(this._map);
        return;
      }
      if (!this._mapResolvers) {
        this._mapResolvers = [];
      }
      this._mapResolvers.push(resolve);
    });
  },

  setMap(map) {
    this._map = map;
    if (!!this._mapResolvers) {
      this._mapResolvers.forEach(resolve => resolve(map));
    }
  },

   removeCurrentMap(){
    if (this._map) {
      this._map.remove();
      this._map = undefined;
    }
  },

    addStyleRaster(){
      const styles = this.selStyle.url.split('/');
      this.map.addSource('basemap-style-source', {
        type: 'raster',
        scheme: 'xyz',
        tiles: [
          `https://api.mapbox.com/styles/v1/snsqss/${styles[styles.length - 1]}/tiles/512/{z}/{x}/{y}?access_token=${this.mapboxToken}`
        ]
      })
      this.map.addLayer({
        id: 'basemap-style-layer',
        type: 'raster',
        source: 'basemap-style-source',
        layout: {}
      }, 'split-layer');
    },

    addBorder(){
      if (this.map.getLayer('province-border')) {
        this.map.removeLayer('province-border');
      }
      if (this.map.getLayer('city-border')) {
        this.map.removeLayer('city-border');
      }
      if (this.isPronvince && !this.map.getLayer('province-border')) {
        this.map.addLayer({
          id: 'province-border',
          type: 'line',
          'source': {
            'scheme':'tms',
            'type': 'vector',
            'tiles': [
                geoserver + '/gwc/service/tms/1.0.0/air:region@EPSG:900913@pbf/{z}/{x}/{y}.pbf'
            ]
          },
          'source-layer': 'region',
          filter: ['==', 'level', 1],
          minzoom: 1,
          maxzoom: 19,
          paint: {
            'line-color': '#2749B7',
            'line-width': 2
          }
        });
      }
      if (this.isCity && !this.map.getLayer('city-border')) {
        this.map.addLayer({
          id: 'city-border',
          type: 'line',
          'source': {
            'scheme':'tms',
            'type': 'vector',
            'tiles': [
              geoserver + '/gwc/service/tms/1.0.0/air:region@EPSG:900913@pbf/{z}/{x}/{y}.pbf'
            ]
          },
          'source-layer': 'region',
          filter: ['all', ['==', 'name', city], ['==', 'level', 2]],
          minzoom: 1,
          maxzoom: 19,
          paint: {
            'line-color': '#ff9800',
            'line-width': 2
          }
        });
      }
    },

    async fitBounds(){
      if (!this.isPronvince && !this.isCity) {
        return;
      }
      const res = cityGeoJson;
      // const data = await res.json();
      const data = cityGeoJson;
      const geojson = data.features.find((i) => i.properties.name === city);
      const box = turf.bbox(this.isPronvince ? data : geojson);
      this.map.fitBounds([[box[0], box[1]], [box[2], box[3]]], {
        padding: 75,
        linear: false,
        animate: false
      });
    }
  },
}
</script>
<style>
@import url('https://api.tiles.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.css');
</style>
<style lang="scss" scoped>
  .popover-style{
    position:absolute;top:10px;left:10px;z-index:10000; 
    .btn{
      overflow:hidden;
      border-radius: 4px;
      border: 2px solid #fff;
      box-shadow: 0 1px 5px rgba(0, 0, 0 , 0.3);
      background:#fff;
      text-align:center;
      font-size:12px;
      cursor: pointer;
      position:relative;
      img{float:left;}
      .tag{
        position:absolute;bottom:0px;right:0px;z-index:2;
      }
    }
  }
  .popover-list{
    .item{text-align:center;}
    .img{
        // width:80px;
        height:60px;
        overflow:hidden;
        border-radius: 4px;
        border: 2px solid #fff;
        box-shadow: 0 1px 5px rgba(0, 0, 0 , 0.3);
        cursor: pointer;
        &.active {
            border-color: #2749b7;
        }
        img{margin:0 auto;}
      }
  }
</style>